/*
* @file Loudspeaker.h
* @brief This file contains the definition of the Loudspeaker class
* @author feiniao
* @version 1.0
* @date 2025-5-11
*/

#ifndef _LOUDSPEAKER_H_
#define _LOUDSPEAKER_H_

#include "bsp_i2s.h"
#include "esp_log.h"
#include "esp_spiffs.h"
#include <string.h>
#include <stdio.h>

#define TAG "Loudspeaker"


#define DIN_PIN 7
#define BCLK_PIN 15
#define LRC_PIN 16
#define SAMPLE_RATE            16000

class Loudspeaker {
private:
    BSP_I2S loudspeaker;
public:
    Loudspeaker();

    ~Loudspeaker();

    esp_err_t play(const void* buffer, size_t bytes_to_write);
};

#endif

/*
use this code to test the Loudspeaker

#include <cmath>
#include <cstdint>
// 定义音频参数
// constexpr 可在编译时求常量的值
constexpr uint32_t Sample_rate = 8000;  // 采样率
constexpr float FREQUENCY = 440.0f;      // 440Hz (A4音)
constexpr float DURATION = 2.0f;         // 2秒持续时间
constexpr float AMPLITUDE = 0.5f;        // 音量 (0.0到1.0)

// 生成正弦波音频数据
void generateSineWave(int16_t* buffer, size_t sampleCount) {
    for (size_t i = 0; i < sampleCount; ++i) {
        float t = static_cast<float>(i) / Sample_rate;
        float value = AMPLITUDE * sin(2 * M_PI * FREQUENCY * t) * INT16_MAX;
        buffer[i] = static_cast<int16_t>(value);
    }
}

extern "C" void app_main() {
    // 计算需要的样本数
    size_t sampleCount = static_cast<size_t>(Sample_rate * DURATION);
    size_t bufferSize = sampleCount * sizeof(int16_t);
    
    // 分配音频缓冲区
    int16_t* audioBuffer = static_cast<int16_t*>(malloc(bufferSize));
    if (!audioBuffer) {
        ESP_LOGE("MAIN", "无法分配音频缓冲区");
        return;
    }
    
    // 生成音频数据
    generateSineWave(audioBuffer, sampleCount);
    
    // 创建麦克风实例
    Loudspeaker l;
    
    // 播放音频
    ESP_LOGI("MAIN", "开始播放音频...");
    esp_err_t ret = l.play(audioBuffer, bufferSize);
    
    if (ret == ESP_OK) {
        ESP_LOGI("MAIN", "音频播放成功");
    } else {
        ESP_LOGE("MAIN", "音频播放失败: %s", esp_err_to_name(ret));
    }
    
    // 释放资源
    free(audioBuffer);
    
    // 等待播放完成
    vTaskDelay(pdMS_TO_TICKS(static_cast<uint32_t>(DURATION * 1000)));
}
*/